// AWTChoice.cpp: implementation of the AWTChoice class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "awt.h"
#include "AWTChoice.h"
#include "AWTChoicePeer.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

IMPLEMENT_DYNAMIC(AWTChoice, AWTComponent)

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

AWTChoice::AWTChoice()
{
  m_selectedIndex = -1;
	m_itemListener = NULL;
}

AWTChoice::~AWTChoice()
{

}

CString& AWTChoice::getItem(int index)
{
	if (index < -1 || index >= m_items.GetCount()) 
		return m_nullString;
	POSITION pos = m_items.FindIndex(index);	
	return m_items.GetAt(pos);
}

void AWTChoice::addItem(CString& item) 
{
  m_items.AddTail(item);
	if (m_peer != NULL)
		((AWTChoicePeer*)m_peer)->addItem(item, -1);
}

void AWTChoice::insert(CString& item, int index) 
{
	if (index < 0)
		return;
	m_items.InsertAfter(m_items.FindIndex(index), item);
	if (m_peer != NULL)
		((AWTChoicePeer*)m_peer)->addItem(item, index);
}

void AWTChoice::clear() 
{
	if (m_peer != NULL)
		((AWTChoicePeer*)m_peer)->clear();
	m_items.RemoveAll();
}

void AWTChoice::remove(CString& item) 
{
	POSITION pos = m_items.GetHeadPosition();
	int n = 0;
	while (pos != NULL)
	{
		CString s = m_items.GetNext(pos);
		if (s == item)
		{
			remove(n);
		}
		n++;		
	}
}

void AWTChoice::delItems(int start, int end) 
{
	for (int i = end; i >= start; i--) 
	{
	    m_items.RemoveAt(m_items.FindIndex(i));
	}
	AWTChoicePeer* peer = (AWTChoicePeer*)m_peer;
	if (peer != NULL) 
	{
	  peer->delItems(start, end);
	}
}

CString& AWTChoice::getSelectedItem() 
{
	int index = getSelectedIndex();
	return (index < 0) ? m_nullString : getItem(index);
}

CStringArray* AWTChoice::getSelectedObjects() 
{
	if (m_selectedIndex >= 0)
	{
		CStringArray* sel = new CStringArray();
		sel->Add(getItem(m_selectedIndex));
		return sel;	
	}
	return NULL;
}

void AWTChoice::select(int index)
{
	m_selectedIndex = index;
	if (m_peer != NULL)
		((AWTChoicePeer*)m_peer)->select(index);
}

void AWTChoice::select(CString& item)
{
	POSITION pos = m_items.GetHeadPosition();
	int n = 0;
	while (pos != NULL)
	{
		CString s = m_items.GetNext(pos);
		if (s == item)
		{
			select(n);
			return;
		}
		n++;		
	}
	m_selectedIndex = -1;
	if (m_peer != NULL)
		((AWTChoicePeer*)m_peer)->select(-1);
}

void AWTChoice::processItemEvent(AWTItemEvent* e)
{
	if (m_itemListener != NULL) 
		m_itemListener->itemStateChanged(e);
}

CWnd* AWTChoice::createComponent()					 
{
	CWnd* wParent = getParent()->getPeer();
	if (wParent == NULL)
		return wParent;
	CComboBox* pwnd = new AWTChoicePeer(this);
	DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL;
	CRect rc = getBounds();
	rc.bottom = rc.top + 100;
	pwnd->Create(dwStyle, rc, wParent, 0);
	pwnd->SetFont(CFont::FromHandle(m_font));
	POSITION pos = m_items.GetHeadPosition();
	while (pos != NULL)
	{
		((AWTChoicePeer*)pwnd)->addItem(m_items.GetNext(pos), -1);
	}
	pwnd->SetCurSel(m_selectedIndex);
	if (!m_enabled)
		pwnd->EnableWindow(FALSE);
	return pwnd;
}

CSize AWTChoice::getMinimumSize()
{
	return getPreferredSize();
}

CSize AWTChoice::getPreferredSize()
{
	HDC hdc = ::GetDC(NULL);
	CDC* pdc = CDC::FromHandle(hdc);
	CFont* ft = CFont::FromHandle(m_font);
	CFont* ftOld = pdc->SelectObject(ft);
	TEXTMETRIC tm;
	pdc->GetTextMetrics(&tm);

	int x = ::GetSystemMetrics(SM_CXVSCROLL) + 10;
	int width = x;
	CSize size;
	POSITION pos = m_items.GetHeadPosition();
	int n = 0;
	while (pos != NULL)
	{
		CString s = m_items.GetNext(pos);
		size = pdc->GetTextExtent(s);
		width = max(width, size.cx + x);
	}
	
	pdc->SelectObject(ftOld);
	::ReleaseDC(NULL, hdc);	

	CSize sz(width, tm.tmHeight + 6);
	return sz;
}
